package code;

import java.io.FileWriter;
import java.util.Random;

import weka.classifiers.Evaluation;
import weka.classifiers.rules.OneR;
import weka.core.Instances;


public class ScanParamsOneR {
	
	//ATTRIBUTES
	private String[] path;
	
	public ScanParamsOneR(String[] args) {
		path = args;
	}

	public void execute() throws Exception{
		//LOAD DATA FILE
		Instances data = DataFiles.getInstance().loadDataFile(path[0]);
		Instances dataTest = DataFiles.getInstance().loadDataFile(path[1]);
	
		//LOAD WRITER FILE
		FileWriter ficheroGuardado = DataFiles.getInstance().loadWriterFile(path[2]);
		
		// CLASSIFY
		trainAndTest(data, dataTest, ficheroGuardado);
		
	}
	
	private void trainAndTest(Instances data, Instances dataTest, FileWriter ficheroGuardado) throws Exception {
		////////////TRAIN\\\\\\\\\\\\\\\
		//CHOOSE ONER AS ESTIMATOR 
		OneR estimador = new OneR(); 
		Resultado r = new Resultado();
		Evaluation evaluator = new Evaluation(data);
		double c,f = 0.0;
		
		//BARRIDO Y SELECCION DE PARAMETROS
		for(int b=1; b<=data.numInstances(); b++){
			//Solo se calcula en el for el fmeasure, el otro ya se calculara
			evaluator = new Evaluation(data);
			estimador.setMinBucketSize(b); 
			//10-FOLD CROSS VALIDATION
			evaluator.crossValidateModel(estimador, data, 10, new Random(10)); 
			c = evaluator.correct();
			f = evaluator.fMeasure(1); 
			r.actualizarMayor(b, f, c); 
	    }
		estimador.setMinBucketSize(r.getB());
		r.imprimirValores(); 
		//imprimir todas las figuras de merito
		
		////////////TEST\\\\\\\\\\\\\\\
		test(evaluator, estimador, data, dataTest, ficheroGuardado);
	}	
	
	private void test(Evaluation evaluator, OneR estimador, Instances data, Instances dataTest, FileWriter ficheroGuardado) throws Exception{
		estimador.buildClassifier(data);	         

	    //LET THE MODEL PREDICT THE CLASS FOR EACH INSTANCE IN THE TEST SET
	    evaluator.evaluateModel(estimador, dataTest);
	  
	    //SAVE DATA IN FILE
	    ficheroGuardado.write("Numero de instancias: ");
	    ficheroGuardado.write(dataTest.numInstances()+"\n");

	    String valorNominal;
	    for (int i=0; i<dataTest.numInstances(); i++) {	    
	    	//EVALUATE THE CLASSIFIER ON A SINGLE INSTANCE AND RECORD THE PREDICTION
	    	if (evaluator.evaluateModelOnceAndRecordPrediction((OneR)estimador, dataTest.instance(i))== 1.0){
	    		valorNominal="no";
	    	}else{
	    		valorNominal="yes";
	    	}
	    ficheroGuardado.write("Evaluador: "+valorNominal+"\n");
	    }
		//CLOSE THE FILE
		ficheroGuardado.close();
	}

}
